package com.site.common.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/** ReactiveRedisTemplate序列化 与 RedisTemplate序列化
 * 教程参考地址：https://lequ7.com/guan-yu-redisreactivespring-shi-zhan-xiang-ying-shi-redis-jiao-hu.html
 * @author xiaochi
 * @date 2022/8/9 14:33
 * @desc
 */
//@Configuration
public class Redis2Config {
    /*
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private Integer port;

    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        // 单机版配置
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);

        GenericObjectPoolConfig<Object> poolConfig = new GenericObjectPoolConfig<Object>();

        LettuceClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder()
                .poolConfig(poolConfig)
                .build();
        return new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
    }*/

    /**
     * RedisTemplate 序列化
     * @param redisConnectionFactory
     * @return
     */
    //@Bean
    //public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 配置 ObjectMapper 包含类型信息,反序列化时需要
		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
		jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setStringSerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }

    /**
     * ReactiveRedisTemplate 序列化
     * @param reactiveRedisConnectionFactory
     * @return
     */
    //@Bean
    //public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory){
    public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(ReactiveRedisConnectionFactory reactiveRedisConnectionFactory){
        //StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        RedisSerializationContext.RedisSerializationContextBuilder<String, Object> serializationContext = RedisSerializationContext.newSerializationContext();
        serializationContext.key(StringRedisSerializer.UTF_8);
        serializationContext.hashKey(StringRedisSerializer.UTF_8);
        serializationContext.value(RedisSerializer.json());
        serializationContext.hashValue(StringRedisSerializer.UTF_8);
        return new ReactiveRedisTemplate<>(reactiveRedisConnectionFactory,serializationContext.build());
    }
}
